/****************************************************************************

	COPYRIGHT(C) MAXSI SOFTWARE, JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010

    This file is part of Maxsi MapSync.

    Maxsi MapSync is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Maxsi MapSync is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Maxsi MapSync. If not, see <http://www.gnu.org/licenses/>.

	*/ #include "MaxsiMapSyncContributors.h" /*

	If you modify this file, please enter your name below and provide contact
	information in MaxsiMapSyncContributors.h. For more information please see
	MaxsiMapSyncContributors.h.
	
	Contributors to this file:

	- Jonas 'Sortie' Termansen
	- [your name here]

	MaxsiMapSync.exe
	A tool that preprocesses maps just before compiling them.

	MaxsiMapSync.cpp
	Main stuff, such as the main function? :P

****************************************************************************/

#include "MaxsiEngine.h"
#include <io.h>
#include <direct.h>
#include <iostream> 
#include <fcntl.h>
#include <SYS\Stat.h>
#include "General.h"
//#include "VMF.h"
//#include "EntryParser.h"
#include "Main.h"

using namespace std;

struct		VISGroup
{
	char*	Name;
	size_t	Id;
	bool	Keep;
};

long		MapSize		=	0;
char*		MapData		=	0;
char*		MISFile		=	0;
List		VISGroups	=	0;
int			calls		=	0;

MISFUNCH(MapSyncImport);
MISFUNCH(MapSyncVisGroupDisable);
MISFUNCH(MapSyncVisGroupEnable);
MISFUNCH(MapSyncExport);
MISFUNCH(MapSyncAppend);

int	faststrcmp(const char* str1,const char* str2)
{
	calls++;
	size_t	len1		=	strlen(str1);
	size_t	len2		=	strlen(str2);

	if (len1 != len2) { return 1; }
	
	size_t	n			=	0;

	for (n	= 0; n < len1; n++)
	{
		if (str1[n] != str2[n] )
		{
			return 1;
		}
	}
	return 0;
}

MISFUNC(MapSyncVisGroupDisable, MaxsiMapSync)
{
	cout << "VISDisable:	"	<<	In[0]	<< "\n";
	if ( !VISGroups )
	{
		VISGroups	=	CreateList(1);
		VISGroup		Group;

		Group.Name	=	BuildString(1,In[0]);
		Group.Keep	=	false;

		SetListEntry(VISGroups,GetListSize(VISGroups)-1,(char*)&Group,sizeof(Group));
	}
	else
	{
		VISGroup		Group;

		Group.Name	=	BuildString(1,In[0]);
		Group.Keep	=	false;
		
		SetListSize	(VISGroups,GetListSize(VISGroups)+1);
		SetListEntry(VISGroups,GetListSize(VISGroups)-1,(char*)&Group,sizeof(Group));
	}
	return 1;
}

MISFUNC(MapSyncVisGroupEnable, MaxsiMapSync)
{
	cout << "VISEnable:	"	<<	In[0]	<< "\n";
	if ( !VISGroups )
	{
		VISGroups	=	CreateList(1);
		VISGroup		Group;

		Group.Name	=	BuildString(1,In[0]);
		Group.Keep	=	true;

		SetListEntry(VISGroups,GetListSize(VISGroups)-1,(char*)&Group,sizeof(Group));
	}
	else
	{
		VISGroup		Group;

		Group.Name	=	BuildString(1,In[0]);
		Group.Keep	=	true;
		
		SetListSize	(VISGroups,GetListSize(VISGroups)+1);
		SetListEntry(VISGroups,GetListSize(VISGroups)-1,(char*)&Group,sizeof(Group));
	}
	return 1;
}

MISFUNC(MapSyncImport, MaxsiMapSync)
{
	if ( GetListSize(In()) != 1 ) { return -1; }

	int		fh					=	0;
	char*	MapFile				=	0;

	// Find the mapsrc folder
	size_t	LastForwardSlash	=	FindCharPrev(MISFile,'/' ,strlen(MISFile));
	size_t	LastBackSlash		=	FindCharPrev(MISFile,'\\',strlen(MISFile));

	size_t	LastSlash			=	min(LastForwardSlash,LastBackSlash);

	if ( LastSlash == -1 )
	{
		// No slash was found!
		cout << "File " << MISFile << " is not in a valid folder!\n";

		return -1;
	}
	
	size_t		MapFileLen		=	LastSlash+1+strlen(In[0])+strlen(".vmf");
				MapFile			=	new char[MapFileLen+1];

	memcpy(MapFile,MISFile,LastSlash+1);
	memcpy(MapFile+LastSlash+1,In[0],strlen(In[0]));
	memcpy(MapFile+LastSlash+1+strlen(In[0]),".vmf",strlen(".vmf"));

	MapFile[MapFileLen]			=	0;

	// First copy the file into memory
	_sopen_s(&fh,MapFile,O_BINARY | O_RDONLY,_SH_DENYNO,_S_IREAD | _S_IWRITE);
	
	if (fh == -1)
	{	
		cout << "Couldn't open " << MapFile << " for reading\n";
		delete[] MapFile;
		return -1;
	}
	else
	{
		if ( MapData ) { delete[] MapData; }

		MapSize = _filelength(fh);

		cout << "Loading " << MapSize << " bytes...";

		DWORD	StartLoad = GetTickCount();
		MapData = new char[MapSize+1];


		_read(fh,MapData,MapSize);
		
		
		MapData[MapSize] = 0;

		_close(fh);
		
		DWORD	EndLoad = GetTickCount();

		cout << " (" << (EndLoad-StartLoad)/1000.0f << ")\n\n";
	}

	delete[] MapFile;

	return 1;
}


int main(int argc, char** argv)
{
	DWORD EndLoad, StartLoad, Result;
	DWORD Duration;
	
	StartLoad = GetTickCount();

	cout << Product_Version_Info << "\n\n";

	Result = RunProgram(argc,argv);

	EndLoad = GetTickCount();
	Duration = (EndLoad-StartLoad)/1000.0;

	DWORD Seconds = Duration % 60;
	Duration -= Duration % 60;
	DWORD Minutes = (Duration % 3600) / 60;
	Duration -= Duration % 3600;
	DWORD Hours = Duration / 3600;

	cout << "\n";

	if (Hours > 0)
	{
		cout << Hours << " hours, ";
	}
	if (Minutes > 0||Hours > 0)
	{
		cout << Minutes << " minutes, ";
	}
	cout << Seconds << " seconds elapsed";
#define OMGZXZZZZZZ
#undef OMGZXZZZZZZ
#ifdef OMGZXZZZZZZ//_DEBUG
	if ( Result == -1 ) // ERROR
	{
		cout << "\n\nAn error occuring during execution.";
	}
	// If in debug mode, let us have a chance to catch the output. :D
	cout << "\nDebug Mode - Press Enter to close the application.";
	cin.get();
#else
	if ( Result == -1 ) // ERROR
	{
		cout << "An error occuring during execution. Press Enter to terminate the application.";
		cin.get();
	}
#endif
	return 0;
}

int Usage( void )
{
	cout <<	"	Usage:\n";
	cout << "	MaxsiMapSync.exe <Map .mis file without file extension>";
	cout << "\n\n";
	cout << "	Example:\n";
	cout << "	MaxsiMapSync.exe \"C:/MapSrc/MyMap\"";
	cout << "\n\n";
	cout << "Press Enter to close the application.";
	cin.get();
	return 1;
}

int RunProgram(int argc, char** argv)
{
	if (argc<2)
	{
		return Usage();
	}

	/*char**/	MISFile		=	BuildString(2,argv[argc-1],".mis");
	char*		MISData		=	0;
	long		MISSize		=	0;

	cout	<<	"MIS:	"	<<	MISFile		<<	"\n\n";

	int	fh	=	0;

	_sopen_s(&fh,MISFile,O_BINARY | O_RDONLY,_SH_DENYNO,_S_IREAD | _S_IWRITE);
	
	if (fh  == -1)
	{	
		cout << "Couldn't open " << MISFile << " for reading!\n";
		return -1;
	}
	else
	{

		MISSize = _filelength(fh);

		cout << "Loading " << MISSize << " bytes...";

		DWORD	StartLoad = GetTickCount();
		MISData = new char[MISSize+1];


		_read(fh,MISData,MISSize);
		
		
		MISData[MISSize] = 0;

		_close(fh);
		
		DWORD	EndLoad = GetTickCount();

		cout << " (" << (EndLoad-StartLoad)/1000.0f << ")\n\n";
	}

	MISRun(MISData,"MaxsiMapSync");


	if ( MapData )
	{
		delete[]	MapData;
	}
	if ( MISFile )
	{
		delete[]	MISFile;
	}

	return 1;
}

// This function is badly written, but works, but a rewrite would be nice.
MISFUNC(MapSyncExport,MaxsiMapSync)
{	
	DWORD	StartLoad = GetTickCount();
	cout << "\nExporting " << In[0] << "...";


	if ( GetListSize(In()) != 1 ) { return -1; }

	int		fh					=	0;
	char*	MapFile				=	0;

	// Find the mapsrc folder

	size_t	LastForwardSlash	=	FindCharPrev(MISFile,'/' ,strlen(MISFile));
	size_t	LastBackSlash		=	FindCharPrev(MISFile,'\\',strlen(MISFile));

	size_t	LastSlash			=	min(LastForwardSlash,LastBackSlash);

	if ( LastSlash == -1 )
	{
		// No slash was found!

		cout << "File " << MISFile << " is not in a valid folder!\n";

		return -1;
	}
	
	size_t		MapFileLen		=	LastSlash+1+strlen(In[0])+strlen(".vmf");
				MapFile			=	new char[MapFileLen+1];

	memcpy(MapFile,MISFile,LastSlash+1);
	memcpy(MapFile+LastSlash+1,In[0],strlen(In[0]));
	memcpy(MapFile+LastSlash+1+strlen(In[0]),".vmf",strlen(".vmf"));

	MapFile[MapFileLen]			=	0;

	// First copy the file into memory
	_sopen_s(&fh,MapFile,O_BINARY | O_WRONLY | O_CREAT | _O_TRUNC ,_SH_DENYNO,_S_IREAD | _S_IWRITE);
	
	if (fh  == -1)
	{	
		cout << "Couldn't open " << MapFile << " for reading\n";
	}
	else
	{
		// Parse the .vmf and write to the file
		size_t	Read			=	0;
		size_t	LineS			=	0;
		size_t	LineL			=	0;
		size_t	Level			=	0;
		size_t	VarS			=	0;
		size_t	VarL			=	0;
		size_t	ParS			=	0;
		size_t	ParL			=	0;
		size_t	Begun			=	0;
		char*	Line			=	0;
		char*	Var				=	0;
		char*	Par				=	0;
		char*	StoredPar		=	0;
		bool	ShouldntParse	=	false;
		bool	versioninfo		=	false;
		bool	visgroup		=	false;
		bool	visgroups		=	false;
		bool	viewsettings	=	false;
		bool	cameras			=	false;
		bool	cordon			=	false;
		bool	world			=	false;
		bool	solid			=	false;
		bool	editor			=	false;
		bool	hidden			=	false;
		bool	entity			=	false;
		bool	ShouldOutput	=	true;
		char*	NL				=	"\r\n";
		size_t	NLL				=	strlen(NL);
		size_t	LastRead		=	-1;
		size_t	LineNum			=	0;
		char	OldEnd			=	0;
		int		cVISBelong[64]		 ; // HACK: Make this support more groups.
		int		nVISBelong		=	0;

		while (true)
		{
			if ( Read >= MapSize) { break; }
			LineNum++;
			if ( Read == LastRead )
			{
				cout << "Loop detected. Aborting.";
				break;
			}
			LastRead	=	Read;

			// Read the line
			LineS		=	SkipWhiteSpace(MapData+Read,MapSize-Read);
			LineL		=	NextLine(MapData+Read+LineS,MapSize-Read-LineS);

			// Cache the line
			//Line		=	new char[LineL+1];
			//memcpy(Line,MapData+Read+LineS,LineL);
			//Line[LineL]	=	0;
			Line		=	MapData+(Read+LineS);
			OldEnd		=	Line[LineL];
			Line[LineL]	=	0;

			if ( faststrcmp(Line,"{")==0)
			{
				Level++;
			}
			else if ( faststrcmp(Line,"}")==0)
			{
				Level--;
				if ( Level == 0 && versioninfo ) 
				{
					ShouldntParse	=	true;
					versioninfo		=	false;
				}
				if ( Level == 0 && viewsettings ) 
				{
					ShouldntParse	=	true;
					viewsettings	=	false;
				}
				if ( Level == 0 && visgroups ) 
				{
					ShouldntParse	=	true;	
					visgroups		=	false;
				}
				if ( Level == 0 && cameras ) 
				{
					ShouldntParse	=	true;
					cameras			=	false;
				}
				if ( Level == 0 && cordon ) 
				{
					ShouldntParse	=	true;
					cordon			=	false;
				}
				if ( Level == 0 && world ) 
				{
					ShouldntParse	=	true;
					world			=	false;
				}
				if ( !hidden && world && Level == 1 && solid) 
				{					
					solid			=	false;

					// Simply output the brush
					if ( ShouldOutput )
					{
						ShouldntParse	=	true;
						_write(fh,MapData+Begun,Read-Begun);
					}
					else
					{
						ShouldntParse	=	false;
					}
				}
				if ( !hidden && Level == 0 && entity) 
				{					
					entity			=	false;

					// Simply output the brush
					if ( ShouldOutput )
					{
						ShouldntParse	=	true;
						_write(fh,MapData+Begun,Read-Begun);
					}
					else
					{
						ShouldntParse	=	false;
					}
				}
				if ( hidden && world && Level == 2 && solid) 
				{					
					solid			=	false;

					// Simply output the brush
					if ( ShouldOutput )
					{
						ShouldntParse	=	true;
						_write(fh,MapData+Begun,Read-Begun);
					}
					else
					{
						ShouldntParse	=	false;
					}
				}
				if ( hidden && Level == 1 && entity) 
				{					
					entity			=	false;

					// Simply output the brush
					if ( ShouldOutput )
					{
						ShouldntParse	=	true;

						_write(fh,MapData+Begun,Read-Begun);

						// Hacky, but should work

						_write(fh,"		}\r\n",strlen("		}\r\n"));
					}
					else
					{
						ShouldntParse	=	false;
					}
				}
				if ( editor) 
				{
					ShouldOutput = true;

					// test if this should be done

					if ( !(entity && Level == 3) )
					{
						// Test if the brush/entity should be written to the final map
						size_t		nVISGroups	=	GetListSize(VISGroups);

						for (size_t N = 0; N < nVISGroups; N++)
						{
							VISGroup* Group		=	(VISGroup*)GetListEntry(VISGroups,(unsigned int)N);
							for (size_t I = 0; I < nVISBelong; I++)
							{
								if ( Group->Id == cVISBelong[I])
								{
									ShouldOutput = Group->Keep;
								}
							}
						}
						
						// Do a minor edit to the vmf if we're shown
						if ( ShouldOutput )
						{
							size_t Offset = FindStringEx(MapData+Begun,Read-Begun,"\"visgroupshown\" \"0\"",strlen("\"visgroupshown\" \"0\""));
							if ( Offset != -1)
							{
								char* Place = MapData+Begun+Offset;
								buf_replace(MapData+Begun,Read-Begun,"\"visgroupshown\" \"0\"",strlen("\"visgroupshown\" \"0\""),"\"visgroupshown\" \"1\"",strlen("\"visgroupshown\" \"1\""));
								Place	= Place;
							}
						}

						memset(&cVISBelong,0,64*sizeof(int));
						nVISBelong				=	0;
					}
					
					editor			=	false;
				}
				if ( Level == 1 && hidden) 
				{
					ShouldntParse	=	false;
					hidden			=	false;
				}
				if ( Level == 0 && hidden) 
				{
					ShouldntParse	=	false;
					hidden			=	false;
				}
				if ( Level == 1 && visgroup ) 
				{
					visgroup		=	false;
				}	
			}
			else if ( (Level == 0) && (faststrcmp(Line,"versioninfo")==0))
			{
				// This shouldn't be parsed, so just output/skip the buffer
				ShouldntParse	=	true;
				versioninfo		=	true;
			}
			else if ( (Level == 0) && (faststrcmp(Line,"visgroups")==0))
			{
				// Simply output it, but make sure it's read as well!
				ShouldntParse	=	true;
				visgroups		=	true;
			}
			else if ( (Level == 1) && (faststrcmp(Line,"visgroup")==0))
			{
				visgroup		=	true;
			}
			else if ( (Level == 0) && (faststrcmp(Line,"viewsettings")==0))
			{
				// This shouldn't be parsed, so just output/skip the buffer
				ShouldntParse	=	true;
				viewsettings	=	true;
			}
			else if ( (Level == 0) && (faststrcmp(Line,"cameras")==0))
			{
				// This shouldn't be parsed, so just output/skip the buffer
				ShouldntParse	=	true;
				cameras			=	true;
			}
			else if ( (Level == 0) && (faststrcmp(Line,"cordon")==0))
			{
				// This shouldn't be parsed, so just output/skip the buffer
				ShouldntParse	=	true;
				cordon			=	true;
			}
			else if ( (Level == 0) && (faststrcmp(Line,"world")==0))
			{
				// This shouldn't be parsed, so just output/skip the buffer
				ShouldntParse	=	true;
				world			=	true;
			}
			else if ( world && (Level == 1) && (faststrcmp(Line,"solid")==0))
			{
				// Don't output now, simply parse the data and decide if it should output or not.
				ShouldntParse	=	false;
				solid			=	true;
				ShouldOutput	=	true; // Because we're NOT in a hidden, this should be enabled by default
				Begun			=	Read;
			}
			else if ( hidden && world && (Level == 2) && (faststrcmp(Line,"solid")==0))
			{
				// This is by default hidden because it's already hidden
				// only include if part of an Enabled VISGroup

				// Don't output now, simply parse the data and decide if it should output or not.
				ShouldntParse	=	false;
				solid			=	true;
				ShouldOutput	=	false;
				Begun			=	Read;
			}
			else if ( faststrcmp(Line,"hidden")==0)
			{
				ShouldntParse	=	false;
				hidden			=	true;
			}
			else if (faststrcmp(Line,"editor")==0)
			{
				editor			=	true;
			}
			else if ( (Level == 0) && (faststrcmp(Line,"entity")==0))
			{
				// Don't output now, simply parse the data and decide if it should output or not.
				ShouldntParse	=	false;
				entity			=	true;
				ShouldOutput	=	true; // Because we're NOT in a hidden, this should be enabled by default
				Begun			=	Read;
			}
			else if ( hidden && (Level == 1) && (faststrcmp(Line,"entity")==0))
			{
				// This is by default hidden because it's already hidden
				// only include if part of an Enabled VISGroup

				// Don't output now, simply parse the data and decide if it should output or not.
				ShouldntParse	=	false;
				entity			=	true;
				ShouldOutput	=	false;
				Begun			=	Read;
			}

			// Simply store the Id's of all the VISGroups!
			// We're going to need them later!
			if ( visgroup && NextWhiteSpace(Line)!=-1)
			{
				VarS			=	0;
				VarL			=	NextWhiteSpace(Line);
				if ( VarL )
				{
					Var			=	new char[VarL+1];
					Var[VarL]	=	0;
					memcpy(Var,Line+VarS,VarL);
					
					if (faststrcmp(Var,"\"name\"")==0||faststrcmp(Var,"\"visgroupid\"")==0)
					{
						// Find the parameter
						ParS		=	VarL+SkipWhiteSpace(Line+VarL);
						ParL		=	LineL-ParS;	// Read the rest of the line!
						Par			=	new char[ParL+1];
						Par[ParL]	=	0;
						memcpy(Par,Line+ParS,ParL);

						if (faststrcmp(Var,"\"name\"")==0)
						{
							if ( StoredPar ) { delete[] StoredPar; }
							StoredPar	=	EvaluateQuote(Par);
						}
						else
						{
							Par[strlen(Par)-1] = 0;
							int	Id		=	atoi(Par+1);

							size_t		nVISGroups	=	GetListSize(VISGroups);

							for (size_t N = 0; N < nVISGroups; N++)
							{
								VISGroup* Group		=	(VISGroup*)GetListEntry(VISGroups,(unsigned int)N);
								if ( faststrcmp(Group->Name,StoredPar) == 0)
								{
									Group->Id	=	Id;
								}
							}							
						}

						delete[] Par;

					}
					
					delete[] Var;
				}				
			}

			// If we're inside a solid, simply try and figure out if we should exist or not
			if ( editor && NextWhiteSpace(Line)!=-1)
			{
				VarS			=	0;
				VarL			=	NextWhiteSpace(Line);
				if ( VarL )
				{
					Var			=	new char[VarL+1];
					Var[VarL]	=	0;
					memcpy(Var,Line+VarS,VarL);
					
					if (faststrcmp(Var,"\"visgroupid\"")==0)
					{
						// Find the parameter
						ParS		=	VarL+SkipWhiteSpace(Line+VarL);
						ParL		=	LineL-ParS;	// Read the rest of the line!
						Par			=	new char[ParL+1];
						Par[ParL]	=	0;
						memcpy(Par,Line+ParS,ParL);

						char*	IdString	=	EvaluateQuote(Par);
						int		IdInteger	=	atoi(IdString);

						// Save this group

						cVISBelong[nVISBelong]	=	IdInteger;
						nVISBelong++;

						//ShouldOutput = true;

						//size_t		nVISGroups	=	GetListSize(VISGroups);

						//for (size_t N = 0; N < nVISGroups; N++)
						//{
						//	VISGroup* Group		=	(VISGroup*)GetListEntry(VISGroups,(unsigned int)N);
						//	if ( Group->Id == IdInteger)
						//	{
						//		ShouldOutput = Group->Keep;
						//	}
						//}

						delete[] IdString;
						delete[] Par;

					}
					
					delete[] Var;
				}				
			}

			Line[LineL]	= OldEnd;

			if ( (ShouldntParse) )
			{
				_write(fh,MapData+Read,NextLine(MapData+Read,MapSize-Read)+NLL);				
			}

			Read += NextLine(MapData+Read,MapSize-Read)+NLL;

			//delete[] Line;
		}

		_close(fh);

		
		// Clean up!
		if ( StoredPar ) { delete[] StoredPar; }
	}


	// Clean up!

	delete[] MapFile;

	DWORD	EndLoad = GetTickCount();
	cout << " (" << (EndLoad-StartLoad)/1000.0f << ")\n\n";
	
	return 1;
}

// This function is badly written, but works, but a rewrite would be nice.
MISFUNC(MapSyncAppend,MaxsiMapSync)
{	
	if ( GetListSize(In()) != 2 ) { return -1; }

	cout << "\nAppending " << In[1] << " to " << In[0] << "\n";

// Find the mapsrc folder

	size_t	LastForwardSlash	=	FindCharPrev(MISFile,'/' ,strlen(MISFile));
	size_t	LastBackSlash		=	FindCharPrev(MISFile,'\\',strlen(MISFile));

	size_t	LastSlash			=	min(LastForwardSlash,LastBackSlash);

	if ( LastSlash == -1 )
	{
		// No slash was found!

		cout << "File " << MISFile << " is not in a valid folder!\n";

		return -1;
	}
	
	size_t		MapFileLen		=	LastSlash+1+strlen(In[1]);
	char*		MapFile			=	new char[MapFileLen+1];
	int			fh				=	0;

	memcpy(MapFile,MISFile,LastSlash+1);
	memcpy(MapFile+LastSlash+1,In[1],strlen(In[1]));
	MapFile[MapFileLen]			=	0;

	// First copy the file into memory
	_sopen_s(&fh,MapFile,O_BINARY | O_RDONLY,_SH_DENYNO,_S_IREAD | _S_IWRITE);
	
	if (fh  == -1)
	{	
		cout << "Couldn't open " << MapFile << " for reading\n";
		delete[] MapFile;
		return -1;
	}
	else
	{
		if ( MapData ) { delete[] MapData; }

		MapSize = _filelength(fh);

		cout << "Loading " << MapSize << " bytes...";

		DWORD	StartLoad = GetTickCount();
		MapData = new char[MapSize+1];


		_read(fh,MapData,MapSize);
		
		
		MapData[MapSize] = 0;

		_close(fh);
		
		DWORD	EndLoad = GetTickCount();

		cout << " (" << (EndLoad-StartLoad)/1000.0f << ")\n\n";
	}

	delete[] MapFile;

	// Find the mapsrc folder
	
				MapFileLen		=	LastSlash+1+strlen(In[0])+strlen(".vmf");
				MapFile			=	new char[MapFileLen+1];

	memcpy(MapFile,MISFile,LastSlash+1);
	memcpy(MapFile+LastSlash+1,In[0],strlen(In[0]));
	memcpy(MapFile+LastSlash+1+strlen(In[0]),".vmf",strlen(".vmf"));


	MapFile[MapFileLen]			=	0;

	// First copy the file into memory
	_sopen_s(&fh,MapFile,O_BINARY | O_WRONLY | O_APPEND ,_SH_DENYNO,_S_IREAD | _S_IWRITE);
	
	if (fh  == -1)
	{	
		cout << "Couldn't open " << MapFile << " for reading\n";
		delete[] MapFile;
		return -1;
	}
	else
	{
		_write(fh,MapData,MapSize);
		_close(fh);
	}


	// Clean up!

	delete[] MapFile;
	
	return 1;
}